/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.sais.eswn.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Calendar;
import javax.swing.JOptionPane;
import org.sais.eswn.core.GameCore;
import org.sais.eswn.core.Player;

/**
 *
 * @author Romulus
 */
public class ClientSock extends Sock {

    private boolean scan = true;
    private boolean iamwatcher = false;

    public ClientSock(ISockCallback caller, String addr, int port, String playerName, boolean iamwatcher) throws Exception {
        mCaller = caller;
        mPlayerName = playerName;
        mDispatcher = new ClientMessageDispatcher(this);
        this.iamwatcher = iamwatcher;
        if (addr.matches("^(\\d+\\-){3}\\d+$")) {
            addr = addr.replace('-', '.');
        }
        if (addr.equals("")) {
            addr = "127.0.0.1";
        }
        mSocket = new Socket();
        mSocket.connect(new InetSocketAddress(InetAddress.getByName(addr), port), 15000);
        if (iamwatcher) {
            send(mSocket, "$IWANTTOWATCH:");
        } else {
            send(mSocket, "$IWANTTOPLAY:");
        }
        this.start();
    }

    public void newGame() {
        mCore = GameCore.startPlay(mSocket, this, true);
        mCore.setPlayerName(Player.ICH, mPlayerName);
        mCore.send("$PLAYERNAME:" + mPlayerName);
        if (isWatcher()) {
            mCore.setUITitle(GameCore.sDisplayTitle + " (WATCHER)");
        } else {
            mCore.setUITitle(GameCore.sDisplayTitle + " (CLIENT)");
        }
        mCaller.setMessage("Stand by Ready.");
        mCaller.setVisible(false);
    }

    @Override
    public void run() {
        try {
            scan();
        } catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(null, ex.getClass() + "\n" + ex.getMessage(), "run() in ClientSock", JOptionPane.ERROR_MESSAGE);
        }
    }

    @Override
    public void scan() {
        boolean nullkita = false;
        do {
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), "Unicode"));
                String instr;
                while ((instr = in.readLine()) != null && scan) {
                    instr = Fix(instr);
                    if (debug) {
                        Calendar c = Calendar.getInstance();
                        System.out.println("CLISOC " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND) + "/ " + instr);
                    }
                    mDispatcher.dispatch(instr);
                }
            } catch (SocketException ex) {
                if (ex.getMessage().equals("Connection reset")) {
                    JOptionPane.showMessageDialog(null, ex.getMessage(), "Scan() in ClientSock", JOptionPane.ERROR_MESSAGE);
                }
                nullkita = false;
            } catch (IOException ex) {
                ex.printStackTrace();
                //JOptionPane.showMessageDialog(null, ex.getClass()+"\n"+ex.getMessage(), "Scan() in ClientSock", JOptionPane.ERROR_MESSAGE);
                nullkita = false;
            } catch (NullPointerException ex) {
                ex.printStackTrace();
                //JOptionPane.showMessageDialog(null, ex.getClass()+"\n"+ex.getMessage(), "Scan() in ClientSock", JOptionPane.ERROR_MESSAGE);
                nullkita = true;
            }
        } while (nullkita);
    }

    @Override
    public void closeSocket() {
        try {
            mSocket.shutdownOutput();
            mSocket.close();
        } catch (IOException ex) {
            //JOptionPane.showMessageDialog(null, ex.getClass()+"\n"+ex.getMessage(), "closeSocket() in ClientSock", JOptionPane.ERROR_MESSAGE);
            ex.printStackTrace();
        }
        scan = false;
        mSocket = null;
    }

    public boolean isWatcher() {
        return iamwatcher;
    }
}
